package cn.schoolwow.workflow.module.task.action.flow.complete.step.taskType;

import cn.schoolwow.quickdao.domain.DAO;
import cn.schoolwow.quickdao.domain.transaction.Transaction;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.workflow.domain.task.AuditType;
import cn.schoolwow.workflow.domain.task.CompleteTaskRequest;
import cn.schoolwow.workflow.entity.WorkFlowTask;
import cn.schoolwow.workflow.module.common.domain.WorkFlowTaskType;
import cn.schoolwow.workflow.module.common.flow.AddWorkFlowHistoryFlow;

import java.util.List;

public class HandleAfterBeforeSignTaskFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        DAO dao = flowContext.checkInstanceData(DAO.class);
        checkTaskType(flowContext);

        dao.startTransaction(transaction -> {
            flowContext.putTemporaryInstanceData(transaction, Transaction.class);
            checkOperation(flowContext);
        });
        boolean shouldBroken = flowContext.getData("shouldBroken", boolean.class, false);
        if(shouldBroken){
            flowContext.broken("等待其他人处理后加签任务");
        }
    }

    @Override
    public String name() {
        return "处理后加签任务";
    }

    private void checkTaskType(FlowContext flowContext){
        WorkFlowTask workFlowTask = flowContext.checkInstanceData(WorkFlowTask.class);

        if(WorkFlowTaskType.AddAfterSign.value!=workFlowTask.getType()){
            flowContext.brokenCurrentFlow("当前任务不是后加签任务");
        }
    }

    private void checkOperation(FlowContext flowContext){
        CompleteTaskRequest completeTaskRequest = flowContext.checkInstanceData(CompleteTaskRequest.class);
        WorkFlowTask workFlowTask = flowContext.checkInstanceData(WorkFlowTask.class);
        Transaction transaction = flowContext.checkInstanceData(Transaction.class);

        transaction.query(WorkFlowTask.class)
                .addQuery("id", workFlowTask.getId())
                .addQuery("instanceId", workFlowTask.getInstanceId())
                .addQuery("nodeId", workFlowTask.getNodeId())
                .addQuery("type", WorkFlowTaskType.AddAfterSign.value)
                .addUpdate("complete", true)
                .execute()
                .update();
        transaction.commit();
        
        switch (completeTaskRequest.taskType){
            case COMPLETE:{
                complete(flowContext);
            }break;
            case REJECT:{
                reject(flowContext);
            }break;
        }
    }

    private void complete(FlowContext flowContext){
        WorkFlowTask workFlowTask = flowContext.checkInstanceData(WorkFlowTask.class);
        Transaction transaction = flowContext.checkInstanceData(Transaction.class);
        
        flowContext.startFlow(new AddWorkFlowHistoryFlow())
                .putCurrentCompositeFlowData("workFlowInstanceId", workFlowTask.getInstanceId())
                .putCurrentCompositeFlowData("message", "后加签人审核通过任务["+ workFlowTask.getTaskName()+"]")
                .putCurrentCompositeFlowData("assigner", workFlowTask.getAssigner())
                .execute();
        
        //是否全部同意
        List<Boolean> completeList = transaction.query(WorkFlowTask.class)
                .addQuery("instanceId", workFlowTask.getInstanceId())
                .addQuery("nodeId", workFlowTask.getNodeId())
                .addQuery("type", WorkFlowTaskType.AddAfterSign.value)
                .addColumn("complete")
                .execute()
                .getSingleColumnList(Boolean.class);
        int countOfComplete = 0;
        for(Boolean complete:completeList){
            if(complete){
                countOfComplete++;
            }
        }

        //获取审批类型
        int auditTypeInt = workFlowTask.getMata().getIntValue("auditType");
        AuditType auditType = AuditType.getAuditTypeByValue(auditTypeInt);
        switch (auditType){
            case ConcurrentApproval:{
                if(countOfComplete<completeList.size()){
                    flowContext.putCurrentFlowData("shouldBroken", true);
                    return;
                }
            }break;
            case AlternativeApproval:{
                if(countOfComplete==0){
                    flowContext.putCurrentFlowData("shouldBroken", true);
                    return;
                }
            }break;
        }
        deleteUnCompleteAfterSignTask(flowContext);
    }

    private void reject(FlowContext flowContext){
        deleteUnCompleteAfterSignTask(flowContext);
    }

    private void deleteUnCompleteAfterSignTask(FlowContext flowContext){
        WorkFlowTask workFlowTask = flowContext.checkInstanceData(WorkFlowTask.class);
        Transaction transaction = flowContext.checkInstanceData(Transaction.class);

        transaction.query(WorkFlowTask.class)
                .addQuery("instanceId", workFlowTask.getInstanceId())
                .addQuery("nodeId", workFlowTask.getNodeId())
                .addQuery("type", WorkFlowTaskType.AddAfterSign.value)
                .addQuery("complete", false)
                .execute()
                .delete();
    }
}